from django.http import JsonResponse
from django.http import HttpResponse
from django.contrib.auth.hashers import make_password
from utils.serializers import LoginSerializer
from django.views.decorators.csrf import csrf_exempt
from utils.crypto import DECRYPT
from utils.decorators import token_required
from django.views.decorators.http import require_POST
from django.db.models import Q
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
import json
from .models import Device
from .services.device_query import DeviceQuery
from .serializers import serialize_device
from .services.device_storage import DeviceStorage


@token_required
@csrf_exempt
def index(request):
    secret = DECRYPT.encrypt({'status': 'test', 'message': 'Method not allowed'})
    return JsonResponse({'secret':secret}, status=200)

@require_POST
@token_required
@csrf_exempt
def device_add(request):
    res = json.loads(request.body.decode('utf-8'))['secret']
    data = json.loads(DECRYPT.decrypt(res))
    # 数据变化重新清空redis
    store = DeviceStorage()
    store.delete_device()
    id = data.get('id')
    if id:
        device = Device.objects.get(id=id)
        for field in data:
            setattr(device, field,data.get(field))
        setattr(device, 'status','offline')
        device.save()
        secret = DECRYPT.encrypt({'status': 'success', 'message': '操作成功', 'code': 200})
        return JsonResponse({'secret': secret}, status=200)
    name = data.get('name')
    description = data.get('description')
    type = data.get('type')
    status = data.get('status')
    location = data.get('location')
    firmware_version = data.get('firmware_version')
    Device.objects.create(
        name=name,
        description=description,
        type=type,
        status=status,
        location=location,
        firmware_version=firmware_version,
    )
    secret = DECRYPT.encrypt({'status': 'success', 'message': '操作成功', 'code': 200})
    return JsonResponse({'secret': secret}, status=200)
# 数据库中查询数据，且写入redis
def db_search_list(name,page_num,page_size):
    device = Device.objects.filter(
        Q(name__icontains=name)
    ).all().order_by('-created_at')
    paginator = Paginator(device, page_size)
    try:
        list_data = paginator.page(page_num)
    except PageNotAnInteger:
        list_data = paginator.page(1)
    except EmptyPage:
        list_data = paginator.page(1)
    device_lists = []
    # 写入redis
    store = DeviceStorage()
    for device in list_data:
        result = {
            'name': device.name,
            'id': str(device.id),
            'description': device.description,
            'type': device.type,
            'status': device.status,
            'condition':str(device.condition),
            'location': device.location,
            'created_at': device.created_at.isoformat(),
            'updated_at': device.updated_at.isoformat(),
        }
        store.create_device(str(device.id), result)
        device_lists.append(result)
    if paginator.count > 0:
        store._set_device_info({
            'total':paginator.count,
            'page': page_num,
        })
    secret = DECRYPT.encrypt(
        {'total': paginator.count, 'status': 'success', 'data': device_lists, 'message': '操作成功', 'code': 200})
    return secret

@require_POST
@token_required
@csrf_exempt
def device_list(request):
    res = json.loads(request.body.decode('utf-8'))['secret']
    data = json.loads(DECRYPT.decrypt(res))
    if data.get('name'):
        name = data.get('name')
    else:
        name = ''
    pageNum = data.get('pageNum')
    pageSize = data.get('pageSize')

    try:
        # 执行redis查询
        result = DeviceQuery().search(
            keyword=name,
            fields=['name', 'location'],
            page=pageNum,
            page_size=pageSize
        )
        device_info = DeviceQuery()._get_device_info()
        print(result['data'], device_info,bool(device_info))
        total = len(DeviceQuery().get_all_devices())
        if bool(device_info):
            if (len(result['data'])>=1 and int(device_info.get('page'))==int(pageNum) and int(device_info.get('total')) >= int(pageNum)*int(pageSize)) or total == int(device_info.get('total')):
                sorted_data = sorted(result['data'], key=lambda x: x["created_at"], reverse=True)
                secret = DECRYPT.encrypt({'total':int(device_info.get('total')),'status': 'success', 'data': sorted_data, 'message': '操作成功redis', 'code': 200})
                return JsonResponse({'secret': secret}, status=200)
            else:
                secret = db_search_list(name, pageNum, pageSize)
                return JsonResponse({'secret': secret}, status=200)
        else:
            secret = db_search_list(name, pageNum, pageSize)
            return JsonResponse({'secret': secret}, status=200)
    except Exception as e:
        print(name,pageNum,pageSize)
        secret = db_search_list(name,pageNum,pageSize)
        return JsonResponse({'secret': secret}, status=200)

@require_POST
@csrf_exempt
@token_required
def device_info(request):
    res = json.loads(request.body.decode('utf-8'))['secret']
    data = json.loads(DECRYPT.decrypt(res))
    id = data.get('id')
    device = Device.objects.get(id=id)
    data = {
        'name': device.name,
        'id': str(device.id),
        'description': device.description,
        'type': device.type,
        'status': device.status,
        'location': device.location,
        'firmware_version': device.firmware_version,
        'ip_address': device.ip_address,
        'mac_address': device.mac_address,
        'created_at': device.created_at.isoformat(),
        'updated_at': device.updated_at.isoformat(),
    }
    secret = DECRYPT.encrypt({'status': 'error','data': data,'message': '操作成功', 'code': 200})
    return JsonResponse({'secret': secret}, status=200)

@require_POST
@csrf_exempt
@token_required
def delete_device(request):
    res = json.loads(request.body.decode('utf-8'))['secret']
    data = json.loads(DECRYPT.decrypt(res))
    id = data.get('id')
    device = Device.objects.get(id=id)
    device.delete()
    # 数据变化重新清空redis
    store = DeviceStorage()
    store.delete_device()
    secret = DECRYPT.encrypt({'status': 'error', 'message': '操作成功', 'code': 200})
    return JsonResponse({'secret': secret}, status=200)

@require_POST
@csrf_exempt
@token_required
def test_list_device(request):
    res = json.loads(request.body.decode('utf-8'))['secret']
    data = json.loads(DECRYPT.decrypt(res))

    secret = DECRYPT.encrypt({'status': 'error', 'message': '操作成功', 'code': 200})
    return JsonResponse({'secret': secret}, status=200)

# def test():
    # 新增
    # redis_client.sadd("key_1","2",'3','4')
    # print(redis_client.sismember("key_1","4"))
    # redis_client.spop("key_1","1")
    # print(redis_client.sismember("key_1","4"))
    # print(redis_client.smembers("1"))
    # redis_client.zadd("game_ranking", {
    #     "playerA": 350,
    #     "playerB": 500,
    #     "playerC": 420,
    #     "playerD": 500
    # })
    # print(redis_client.zrevrange("game_ranking", 0, -1, withscores=True))

